/*
Author: Surpass-HC
Source: https://gitee.com/hxchuan000/clpc-1
Mail: surpass-hc@qq.com
*/
#include "rbtree_option.h"
static int64_t rbtreeCmpFuncCom(struct rbtreeMgrStct *rbmgr, const struct rbtreeKeyStct *key1, const struct rbtreeKeyStct *key2)
{
    int64_t tmpCmpFlag = 0;
    if(!(rbmgr->keytype == key1->keytype && key1->keytype == key2->keytype))
    {
        logerrorc("tree cmp type diff:%d,%d,%d", rbmgr->keytype, key1->keytype, key2->keytype);
        return -2;
    }
    switch (rbmgr->keytype)
    {
    case rbtreeKeyType_32:
    {
        tmpCmpFlag = key1->key32 - key2->key32;
        break;
    }
    case rbtreeKeyType_64:
    {
        tmpCmpFlag = key1->key64 - key2->key64;
        break;
    }
    case rbtreeKeyType_Str:
    {
        tmpCmpFlag = strncmp(key1->keystr, key2->keystr, sizeof(key1->keystr));
        break;
    }
    case rbtreeKeyType_Mem:
    {
        tmpCmpFlag = memcmp(key1->keystr, key2->keystr, sizeof(key1->keystr));
        break;
    }
    default:
    {
        logerrorc("tree cmp key type err:%d,%d,%d", rbmgr->keytype, key1->keytype, key2->keytype);
        return -2;
    }
    }
    if(tmpCmpFlag > 0)
    {
        return 1;
    }
    else if(tmpCmpFlag < 0)
    {
        return -1;
    }
    return 0;
}

static struct rbtreeNodeStct *rbtreeMgrGetRoot(struct rbtreeMgrStct *rbmgr)
{
    if (!rbmgr)
    {
        logerrorc("");
        return NULL;
    }
    return rb_entry(rbmgr->rbroot.rb_node, struct rbtreeNodeStct, node);
}

int rbtreeMgrFreeNode(struct rbtreeMgrStct *rbmgr, struct rbtreeNodeStct *eraseNode)
{
    rb_erase(&eraseNode->node, &rbmgr->rbroot);
    free(eraseNode);
    return 0;
}

struct rbtreeNodeStct *rbtreeMgrFindNode(struct rbtreeMgrStct *rbmgr, const struct rbtreeKeyStct *findkey)
{
    if (!(rbmgr && findkey))
    {
        logerrorc("");
        return NULL;
    }
    struct rb_node *tempnode = rbmgr->rbroot.rb_node;
    while (tempnode)
    {
        struct rbtreeNodeStct *tmpNode = rb_entry(tempnode, struct rbtreeNodeStct, node);
        switch (rbtreeCmpFuncCom(rbmgr, findkey, &tmpNode->keyval))
        {
        case 0:
        {
            return tmpNode;
        }
        case 1:
        {
            tempnode = tempnode->rb_right;
            break;
        }
        case -1:
        {
            tempnode = tempnode->rb_left;
            break;
        }
        default:
        {
            return NULL;
        }
        }
    }
    return NULL;
}

int rbtreeMgrInsertNode(struct rbtreeMgrStct *rbmgr, struct rbtreeNodeStct *inode)
{
    int tmpflag = 0;
    struct rb_node **insertNodePointer, *parent;
    struct rbtreeNodeStct *tmpUsrNode;
    if (!(rbmgr && inode && rbmgr->keytype == inode->keyval.keytype))
    {
        logerrorc("");
        tmpflag = -2;
        goto insertFreePtr;
    }
    insertNodePointer = &rbmgr->rbroot.rb_node;
    parent = NULL;
    while (*insertNodePointer)
    {
        parent = *insertNodePointer;
        tmpUsrNode = rb_entry(parent, struct rbtreeNodeStct, node);
        switch (rbtreeCmpFuncCom(rbmgr, &inode->keyval, &tmpUsrNode->keyval))
        {
        case 0:
        {
            logerrorc("tree already have node, insert error");
            tmpflag = 0;
            goto insertFreePtr;
        }
        case 1:
        {
            insertNodePointer = &parent->rb_right;
            break;
        }
        case -1:
        {
            insertNodePointer = &parent->rb_left;
            break;
        }
        default:
        {
            tmpflag = -2;
            goto insertFreePtr;
        }
        }
    }
    rb_link_node(&inode->node, parent, insertNodePointer);
    rb_insert_color(&inode->node, &rbmgr->rbroot);
    tmpflag = 1;
insertFreePtr:
    if(tmpflag <= 0)
    {
        free(inode);
    }
    return tmpflag;
}
// 替换数据
int rbtreeMgrReplaceNode(struct rbtreeMgrStct *rbmgr, struct rbtreeNodeStct *inode)
{
    if (!(rbmgr && inode))
    {
        logerrorc("");
        return -2;
    }
    struct rbtreeNodeStct *tempFindData = rbtreeMgrFindNode(rbmgr, &inode->keyval);
    if (tempFindData)
    {
        rbtreeMgrFreeNode(rbmgr, tempFindData);
    }
    return rbtreeMgrInsertNode(rbmgr, inode);
}

int rbtreeMgrEraseByKey(struct rbtreeMgrStct *rbmgr, const struct rbtreeKeyStct *findkey)
{
    if (!(rbmgr && findkey))
    {
        logerrorc("");
        return 0;
    }
    struct rbtreeNodeStct *tmpNode = rbtreeMgrFindNode(rbmgr, findkey);
    if(tmpNode == NULL)
    {
        return 0;
    }
    rbtreeMgrFreeNode(rbmgr, tmpNode);
    return 1;
}

struct rbtreeNodeStct *rbtreeGetLRLimitNode(struct rbtreeMgrStct *rbmgr, int leftLimitFlag)
{
    if (!rbmgr)
    {
        logerrorc("");
        return NULL;
    }
    struct rb_node *tempNode = rbmgr->rbroot.rb_node;
    struct rbtreeNodeStct *tempFindData = NULL;
    while (tempNode)
    {
        struct rb_node *tempChildNode;
        if (leftLimitFlag)
        {
            tempChildNode = tempNode->rb_left;
        }
        else
        {
            tempChildNode = tempNode->rb_right;
        }
        if (tempChildNode)
        {
            tempNode = tempChildNode;
        }
        else
        {
            tempFindData = container_of(tempNode, struct rbtreeNodeStct, node);
            break;
        }
    }
    return tempFindData;
}

// 初始化管理器
int rbtreeMgrInit(struct rbtreeMgrStct *rbmgr, uint8_t setKeyTyep)
{
    if (!rbmgr)
    {
        logerrorc("");
        return -1;
    }
    rbmgr->rbroot = RB_ROOT;
    rbmgr->keytype = setKeyTyep;
    pthread_mutex_init(&rbmgr->rbtreelock, NULL);
    return 0;
}

// 清空管理器
int rbtreeMgrFreeAll(struct rbtreeMgrStct *rbmgr)
{
    pthread_mutex_lock(&rbmgr->rbtreelock);
    while(1)
    {
        struct rbtreeNodeStct *tmpUsrNode = rbtreeMgrGetRoot(rbmgr);
        if(tmpUsrNode)
        {
            rbtreeMgrFreeNode(rbmgr, tmpUsrNode);
        }
        else
        {
            break;
        }
    }
    pthread_mutex_unlock(&rbmgr->rbtreelock);
    pthread_mutex_destroy(&rbmgr->rbtreelock);
    return 0;
}

static void rbtreeExcuteTraversalFunction(struct rb_node *traversalNode, rbTraversalCallback cbkFunc)
{
    struct rbtreeNodeStct *tempNodeInform = rb_entry(traversalNode, struct rbtreeNodeStct, node);
    if (cbkFunc && tempNodeInform)
    {
        cbkFunc(tempNodeInform);
    }
}
// traversalflag,0:前序，1：中序，2：后序
static void rbtreeTraversalNode(struct rb_node *traversalNode, rbTraversalCallback cbkFunc, int traversalflag)
{
    if (!traversalNode)
    {
        return;
    }
    if (traversalflag == 0)
    {
        rbtreeExcuteTraversalFunction(traversalNode, cbkFunc);
    }
    rbtreeTraversalNode(traversalNode->rb_left, cbkFunc, traversalflag);
    if (traversalflag == 1)
    {
        rbtreeExcuteTraversalFunction(traversalNode, cbkFunc);
    }
    rbtreeTraversalNode(traversalNode->rb_right, cbkFunc, traversalflag);
    if (traversalflag == 2)
    {
        rbtreeExcuteTraversalFunction(traversalNode, cbkFunc);
    }
}
// 遍历二叉树。
// traversalflag,0:前序，1：中序，2：后序
void rbtreeMgrTraversal(struct rbtreeMgrStct *rbmgr, rbTraversalCallback cbkFunc, int traversalflag)
{
    rbtreeTraversalNode(rbmgr->rbroot.rb_node, cbkFunc, traversalflag);
}

struct rbtreeNodeStct *rbtreeMallocOneNode(uint8_t setKeyType, uint32_t setValSize)
{
    struct rbtreeNodeStct *tmpUsrNode = (struct rbtreeNodeStct *)malloc(rbtreeNodeHeadSize + setValSize);
    if(!tmpUsrNode)
    {
        logerrorc("");
        return NULL;
    }
    tmpUsrNode->keyval.keytype = setKeyType;
    return tmpUsrNode;
}